import Watcher from "./observe/watcher.js";
import { nextTick } from "./utils.js";
import { patch } from "./vdom/patch.js";

export function lifecycleMixin(Vue) {
  Vue.prototype._update = function (vnode) {
    const vm = this;
    // console.log("_update");
    // 变成真实dom
    // 既有初始化， 又有更新
    // vm._vnode  表示将当前的虚拟节点保存起来
    const prevVnode = vm._vnode;
    if (!prevVnode) {
      vm.$el = patch(vm.$el, vnode);
    } else {
      vm.$el = patch(prevVnode, vnode);
    }
    vm._vnode = vnode;

    // patch(上一次的虚拟节点, vnode)
  };
  Vue.prototype.$nextTick = nextTick;
}

// 后续每个组件渲染的时候都会有一个watcher
export function mountCompenent(vm, el) {
  //   console.log(vm, el);
  //   更新函数， 数据变化后， 会再次调用该函数
  let updateComponent = () => {
    //   调用render函数， 生成虚拟dom
    vm._update(vm._render()); // 后续更新可以调用updateComponent
    // 用虚拟dom 生成真实dom
  };
  // 观察者模式， 属性是被观察者， 观察者就是刷新页面
  // updateComponent();
  callHook(vm, "beforeMount");
  new Watcher(
    vm,
    updateComponent,
    () => {
      console.log("更新视图了");
    },
    true
  ); // true 他是一个渲染watcher，后续有其他的watcher
  callHook(vm, "mounted");
}

// 调用钩子函数
export function callHook(vm, hook) {
  let handlers = vm.$options[hook];
  if (handlers) {
    for (let i = 0; i < handlers.length; i++) {
      handlers[i].call(vm);
    }
  }
}
